from flask import Blueprint, request, jsonify
from database.config import get_postgres_session
from database.models import User
from werkzeug.security import generate_password_hash, check_password_hash
import jwt
import datetime
from functools import wraps

auth_bp = Blueprint('auth', __name__)

# JWT密钥 (在生产环境中应该使用环境变量)
JWT_SECRET = 'your-secret-key-here'

def token_required(f):
    """JWT令牌验证装饰器"""
    @wraps(f)
    def decorated(*args, **kwargs):
        token = request.headers.get('Authorization')
        
        if not token:
            return jsonify({
                'success': False,
                'error': '缺少认证令牌'
            }), 401
        
        try:
            # 移除 'Bearer ' 前缀
            if token.startswith('Bearer '):
                token = token[7:]
            
            data = jwt.decode(token, JWT_SECRET, algorithms=['HS256'])
            current_user_id = data['user_id']
        except jwt.ExpiredSignatureError:
            return jsonify({
                'success': False,
                'error': '令牌已过期'
            }), 401
        except jwt.InvalidTokenError:
            return jsonify({
                'success': False,
                'error': '无效的令牌'
            }), 401
        
        return f(current_user_id, *args, **kwargs)
    
    return decorated

@auth_bp.route('/auth/register', methods=['POST'])
def register():
    """用户注册"""
    session = get_postgres_session()
    try:
        data = request.get_json()
        
        if not data or not all(k in data for k in ('name', 'email', 'password')):
            return jsonify({
                'success': False,
                'error': '姓名、邮箱和密码都是必需的'
            }), 400
        
        # 检查邮箱是否已存在
        existing_user = session.query(User).filter_by(email=data['email']).first()
        if existing_user:
            return jsonify({
                'success': False,
                'error': '该邮箱已被注册'
            }), 400
        
        # 创建新用户
        user = User(
            name=data['name'],
            email=data['email'],
            password_hash=generate_password_hash(data['password']),
            avatar_url=data.get('avatarUrl', 'https://via.placeholder.com/100')
        )
        
        session.add(user)
        session.commit()
        
        # 生成JWT令牌
        token = jwt.encode({
            'user_id': user.id,
            'exp': datetime.datetime.utcnow() + datetime.timedelta(days=30)
        }, JWT_SECRET, algorithm='HS256')
        
        return jsonify({
            'success': True,
            'data': {
                'user': {
                    'id': user.id,
                    'name': user.name,
                    'email': user.email,
                    'avatarUrl': user.avatar_url
                },
                'token': token
            }
        }), 201
        
    except Exception as e:
        session.rollback()
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500
    finally:
        session.close()

@auth_bp.route('/auth/login', methods=['POST'])
def login():
    """用户登录"""
    session = get_postgres_session()
    try:
        data = request.get_json()
        
        if not data or not all(k in data for k in ('email', 'password')):
            return jsonify({
                'success': False,
                'error': '邮箱和密码都是必需的'
            }), 400
        
        # 查找用户
        user = session.query(User).filter_by(email=data['email']).first()
        
        if not user or not check_password_hash(user.password_hash, data['password']):
            return jsonify({
                'success': False,
                'error': '邮箱或密码错误'
            }), 401
        
        # 生成JWT令牌
        token = jwt.encode({
            'user_id': user.id,
            'exp': datetime.datetime.utcnow() + datetime.timedelta(days=30)
        }, JWT_SECRET, algorithm='HS256')
        
        return jsonify({
            'success': True,
            'data': {
                'user': {
                    'id': user.id,
                    'name': user.name,
                    'email': user.email,
                    'avatarUrl': user.avatar_url
                },
                'token': token
            }
        }), 200
        
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500
    finally:
        session.close()

@auth_bp.route('/auth/logout', methods=['POST'])
@token_required
def logout(current_user_id):
    """用户登出 (目前只是一个占位符，实际的令牌失效需要在客户端处理)"""
    return jsonify({
        'success': True,
        'message': '登出成功'
    }), 200

@auth_bp.route('/users/profile', methods=['GET'])
@token_required
def get_profile(current_user_id):
    """获取用户资料"""
    session = get_postgres_session()
    try:
        user = session.query(User).filter_by(id=current_user_id).first()
        
        if not user:
            return jsonify({
                'success': False,
                'error': '用户不存在'
            }), 404
        
        return jsonify({
            'success': True,
            'data': {
                'id': user.id,
                'name': user.name,
                'email': user.email,
                'avatarUrl': user.avatar_url,
                'createdAt': user.created_at.strftime('%Y-%m-%d') if user.created_at else None
            }
        }), 200
        
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500
    finally:
        session.close()

@auth_bp.route('/users/profile', methods=['PUT'])
@token_required
def update_profile(current_user_id):
    """更新用户资料"""
    session = get_postgres_session()
    try:
        user = session.query(User).filter_by(id=current_user_id).first()
        
        if not user:
            return jsonify({
                'success': False,
                'error': '用户不存在'
            }), 404
        
        data = request.get_json()
        
        if data.get('name'):
            user.name = data['name']
        if data.get('email'):
            # 检查新邮箱是否已被其他用户使用
            existing_user = session.query(User).filter(
                User.email == data['email'],
                User.id != current_user_id
            ).first()
            if existing_user:
                return jsonify({
                    'success': False,
                    'error': '该邮箱已被其他用户使用'
                }), 400
            user.email = data['email']
        if 'avatarUrl' in data:
            user.avatar_url = data['avatarUrl']
        
        session.commit()
        
        return jsonify({
            'success': True,
            'data': {
                'id': user.id,
                'name': user.name,
                'email': user.email,
                'avatarUrl': user.avatar_url
            }
        }), 200
        
    except Exception as e:
        session.rollback()
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500
    finally:
        session.close()

@auth_bp.route('/auth/change-password', methods=['POST'])
@token_required
def change_password(current_user_id):
    """修改密码"""
    session = get_postgres_session()
    try:
        user = session.query(User).filter_by(id=current_user_id).first()
        
        if not user:
            return jsonify({
                'success': False,
                'error': '用户不存在'
            }), 404
        
        data = request.get_json()
        
        if not data or not all(k in data for k in ('currentPassword', 'newPassword')):
            return jsonify({
                'success': False,
                'error': '当前密码和新密码都是必需的'
            }), 400
        
        # 验证当前密码
        if not check_password_hash(user.password_hash, data['currentPassword']):
            return jsonify({
                'success': False,
                'error': '当前密码错误'
            }), 401
        
        # 更新密码
        user.password_hash = generate_password_hash(data['newPassword'])
        session.commit()
        
        return jsonify({
            'success': True,
            'message': '密码修改成功'
        }), 200
        
    except Exception as e:
        session.rollback()
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500
    finally:
        session.close()
